/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package hu.bme.j2ee.v37zen.entities;

import hu.bme.j2ee.v37zen.util.Role;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import javax.persistence.CascadeType;
import javax.persistence.CollectionTable;
import javax.persistence.Column;
import javax.persistence.ElementCollection;
import javax.persistence.Entity;
import javax.persistence.EnumType;
import javax.persistence.Enumerated;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.NamedQueries;
import javax.persistence.NamedQuery;
import javax.persistence.OneToMany;
import javax.persistence.Table;

/**
 *
 * @author Kiss Dániel
 */
@Entity
@Table(name="SD_USER")
@NamedQueries({
    @NamedQuery(name="User.findAll", query="SELECT u FROM User u"),
    @NamedQuery(name="User.findUserByUsername", query ="SELECT u FROM User u WHERE u.username = :username"),
    @NamedQuery(name="User.findUserByUsernameEager", query ="SELECT u FROM User u JOIN FETCH u.dials WHERE u.username = :username"),
    @NamedQuery(name="User.findUserByEmail", query ="SELECT u FROM User u WHERE u.email = :email"),
    @NamedQuery(name="User.findUserByLoginState", query ="SELECT u FROM User u WHERE u.logedIn = :logedIn"),
    @NamedQuery(name="User.findUserByDialID", query ="SELECT u FROM User u INNER JOIN u.dials d WHERE d.id = :id")
        /*,
    @NamedQuery(name="User.findUserByRoleSet", query ="SELECT u FROM User u WHERE ")*/
})
public class User implements Serializable {
    private static final long serialVersionUID = -3470372313571399372L;
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;
    @Column(unique = true, nullable = false)
    private String username;
    @Column(unique = true, nullable = false)
    private String email;
    @Column(nullable = false)
    private String password;
    //@OneToMany(cascade = CascadeType.ALL, orphanRemoval = true)
    //private ArrayList<Role> roles;
    @ElementCollection
    @CollectionTable(name="SD_USER_ROLES")
    @Enumerated(EnumType.STRING)
    Set<Role> roles;
    @OneToMany(cascade = CascadeType.ALL, orphanRemoval = true,  fetch = FetchType.LAZY)
    //@OrderBy("DIAL_ORDER")
    @JoinColumn(name="USER_ID")
    private List<Dial> dials;
    
    private boolean logedIn = false;
    @Column(name = "ROLE_A_JAAS_MIATT")
    @Enumerated(EnumType.STRING)
    private Role role_a_JAAS_miatt;

    
    public User(){
        
    }
    
    public User(String username, String email, String password) {
        this(username, email, password,
                Role.SET_of_USER_ONLY,
                new ArrayList<Dial>()
             );
    }
    
    public User(String username, String email, String password, Set<Role> roles) {
        this(username, email, password,
                roles,
                new ArrayList<Dial>()
             );
    }
    
    public User(String username, String email, String password, Set<Role> roles, ArrayList<Dial> dials) {
        this.username = username;
        this.email = email;
        this.password = password;
        this.roles = roles;
        this.dials = dials;
        
        if(roles.contains(Role.ADMIN)){
            this.role_a_JAAS_miatt = Role.ADMIN;
        } else {
            this.role_a_JAAS_miatt = Role.USER;
        }
    }   
    
    /**
     * Get the value of email
     *
     * @return the value of email
     */
    public String getEmail() {
        return email;
    }

    /**
     * Set the value of email
     *
     * @param email new value of email
     */
    public void setEmail(String email) {
        this.email = email;
    }
    
    /**
     * Get the value of username
     *
     * @return the value of username
     */
    public String getUsername() {
        return username;
    }

    /**
     * Set the value of username
     *
     * @param username new value of username
     */
    public void setUsername(String username) {
        this.username = username;
    }
    
    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }
    
    public Set<Role> getRoles() {
        return roles;
    }

    public void setRoles(Set<Role> roles) {
        this.roles = roles;
        
        if(roles.contains(Role.ADMIN)){
            this.role_a_JAAS_miatt = Role.ADMIN;
        } else {
            this.role_a_JAAS_miatt = Role.USER;
        }
    }
    
    public List<Dial> getDials() {
        return dials;
    }

    public void setDials(List<Dial> dials) {
        this.dials = dials;
    }

    public void addDial(Dial dial){
        if(this.dials == null){
            this.dials = new ArrayList<Dial>();
        }
        this.dials.add(dial);
    }
    
    public void removeDial(Dial dial){
        if(this.dials == null){
            return;
        }
        this.dials.remove(dial);
    }

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public boolean isLogedIn() {
        return logedIn;
    }

    public void setLogedIn(boolean logedIn) {
        this.logedIn = logedIn;
    }

    public Role getRole_a_JAAS_miatt() {
        return role_a_JAAS_miatt;
    }

    public void setRole_a_JAAS_miatt(Role role_a_JAAS_miatt) {
        this.role_a_JAAS_miatt = role_a_JAAS_miatt;
    }

        
    
    
    

    @Override
    public int hashCode() {
        int hash = 7;
        hash = 41 * hash + (this.id != null ? this.id.hashCode() : 0);
        hash = 41 * hash + (this.username != null ? this.username.hashCode() : 0);
        hash = 41 * hash + (this.email != null ? this.email.hashCode() : 0);
        hash = 41 * hash + (this.password != null ? this.password.hashCode() : 0);
        hash = 41 * hash + (this.roles != null ? this.roles.hashCode() : 0);
        hash = 41 * hash + (this.dials != null ? this.dials.hashCode() : 0);
        hash = 41 * hash + (this.logedIn ? 1 : 0);
        return hash;
    }

    @Override
    public boolean equals(Object object) {
        // TODO: Warning - this method won't work in the case the id fields are not set
        if (!(object instanceof User)) {
            return false;
        }
        User other = (User) object;
        if ((this.id == null && other.id != null) || (this.id != null && !this.id.equals(other.id))) {
            return false;
        }
        return true;
    }

    @Override
    public String toString() {
        return "User{" + "id=" + id + ", username=" + username + ", email=" + email + ", password=" + password + ", roles=" + roles + ", dials=" + dials + ", logedIn=" + logedIn + '}';
    }  

    
}
